/*
 * Created on 2005/04/26
 * Author aki@www.xucker.jpn.org
 * License Apache2.0 or Common Public License
 */
package jp.sourceforge.akjrcp.ui.draw2d;

import org.eclipse.draw2d.Graphics;
import org.eclipse.swt.graphics.Color;

import org.eclipse.swt.graphics.Point;

/**
 * 
 *
 */
public class SimpleGraphMemoryPainterDraw2D {
    private boolean vGraph;	//vertical or horizontal
    private boolean graphPlus;
    private int mainGridPixel=8;
    private int subGridPixel=4;
    private int subSubGridPixel=2;
    private boolean gridPlus;
    public boolean isDrawLine() {
        return drawLine;
    }
    public void setDrawLine(boolean drawLine) {
        this.drawLine = drawLine;
    }
    public boolean isGraphPlus() {
        return graphPlus;
    }
    public void setGraphPlus(boolean graphPlus) {
        this.graphPlus = graphPlus;
    }
    public boolean isGridPlus() {
        return gridPlus;
    }
    public void setGridPlus(boolean gridPlus) {
        this.gridPlus = gridPlus;
    }
 
    public Color getLineColor() {
        return lineColor;
    }
    public void setLineColor(Color lineColor) {
        this.lineColor = lineColor;
    }
    public int getMainGridPixel() {
        return mainGridPixel;
    }
    public void setMainGridPixel(int mainGridPixel) {
        this.mainGridPixel = mainGridPixel;
    }
    public String[] getMainLabel() {
        return mainLabel;
    }
    public void setMainLabel(String[] mainLabel) {
        this.mainLabel = mainLabel;
    }
    public int getMarginGrid() {
        return marginGrid;
    }
    public void setMarginGrid(int marginGrid) {
        this.marginGrid = marginGrid;
    }
    /*
     * maybe default is 100
     */
    public double getPerMain() {
        return perMain;
    }
    public void setPerMain(double perMain) {
        this.perMain = perMain;
    }
    public int getSplitSub() {
        return splitSub;
    }
    public void setSplitSub(int splitSub) {
        this.splitSub = splitSub;
    }
    public int getSplitSubSub() {
        return splitSubSub;
    }
    public void setSplitSubSub(int splitSubSub) {
        this.splitSubSub = splitSubSub;
    }
    public int getSubGridPixel() {
        return subGridPixel;
    }
    public void setSubGridPixel(int subGridPixel) {
        this.subGridPixel = subGridPixel;
    }
    public int getSubSubGridPixel() {
        return subSubGridPixel;
    }
    public void setSubSubGridPixel(int subSubGridPixel) {
        this.subSubGridPixel = subSubGridPixel;
    }
    public Color getTextColor() {
        return textColor;
    }
    public void setTextColor(Color textColor) {
        this.textColor = textColor;
    }
    public boolean isVerticalGraph() {
        return vGraph;
    }
    public void setVerticalGraph(boolean graph) {
        vGraph = graph;
    }
    private String mainLabel[];
    private boolean drawLine;
    
    private Color lineColor=new Color(null,0,0,0);
    private Color textColor=new Color(null,0,0,0);
    private double perMain=100;
    private int splitSub=2;
    private int splitSubSub=5;
    private int marginGrid=2;
    
    
    
    public void draw(Graphics gc,int drawX,int drawY,int length){
         if(vGraph){
             drawVerticalGraph(gc,drawX,drawY,length);
         }else{
             drawHorizontalGraph(gc,drawX,drawY,length);
         }
    }
    
    public void drawVerticalGraph(Graphics gc,int drawX,int drawY,int length){
        //draw Line;
        gc.setForegroundColor(lineColor);
        
        if(graphPlus){
            gc.drawLine(drawX,drawY,drawX,drawY+length);
           
        }else{
            gc.drawLine(drawX,drawY,drawX,drawY-length);
            
        }
        
        
        int duration=1;
        if(!gridPlus){
            duration=-1;
        }
        
        double current=drawY;
        if(graphPlus){
            int index=0;
            while(current<=drawY+length){
                //Draw Main memory
                
                gc.drawLine(drawX,(int)current,drawX+duration*mainGridPixel,(int)current);
                int subPer=(int)(perMain/splitSub);
                int subSubPer=subPer/splitSubSub;
                //Draw Sub memory
                
                for(int i=0;i<splitSub;i++){
                    if(current+subPer*i<drawY+length){
                    if(i!=0){
                    gc.drawLine(drawX,(int)current+subPer*i,drawX+duration*subGridPixel,(int)current+subPer*i);
                    }
                    //Draw Sub Sub memory
                   
                    for(int j=1;j<splitSubSub;j++){
                        if(current+subPer*i+subSubPer*j<drawY+length){
                        gc.drawLine(drawX,(int)current+subPer*i+subSubPer*j,drawX+duration*subSubGridPixel,(int)current+subPer*i+subSubPer*j);
                    }
                    }
                    }
                }
                //Draw Label
                String label=labelAt(index);
                drawLabelVertical(gc,drawX,(int)current,label);
                current+=perMain;
                index++;
            }
        }else{
            int index=0;
            while(current>drawY-length){
                
                //Draw Main memory
                gc.drawLine(drawX,(int)current,drawX+duration*mainGridPixel,(int)current);
                int subPer=(int)(perMain/splitSub);
                int subSubPer=subPer/splitSubSub;
                //Draw Sub memory
                for(int i=0;i<splitSub;i++){
                    if(i!=0){
                    gc.drawLine(drawX,(int)current-subPer*i,drawX+duration*subGridPixel,(int)current-subPer*i);
                    }
                    //Draw Sub Sub memory
                    for(int j=1;j<splitSubSub;j++){
                    gc.drawLine(drawX,(int)current-subPer*i-subSubPer*j,drawX+duration*subSubGridPixel,(int)current-subPer*i-subSubPer*j);
                    }
                }
                //Draw Label
                String label=labelAt(index);
                drawLabelVertical(gc,drawX,(int)current,label);
                current-=perMain;
                index++;
            }
        }
    }
    
    public void drawHorizontalGraph(Graphics gc,int drawX,int drawY,int length){
       // log.infolength:"+length);
        //draw Line;
        gc.setForegroundColor(lineColor);
        
        if(graphPlus){
            gc.drawLine(drawX,drawY,drawX+length,drawY);
            
        }else{
            gc.drawLine(drawX,drawY,drawX-length,drawY);
           
        }
        
        
        int duration=1;
        if(!gridPlus){
            duration=-1;
        }
        
        int current=drawX;
        if(graphPlus){
            int index=0;
            while(current<drawX+length){
                //Draw Main memory
                gc.drawLine(current,drawY,current,drawY+duration*mainGridPixel);
                int subPer=(int)(perMain/splitSub);
                int subSubPer=subPer/splitSubSub;
                //Draw Sub memory
                for(int i=0;i<splitSub;i++){
                    if(i!=0){
                    gc.drawLine(current+subPer*i,drawY,current+subPer*i,drawY+duration*subGridPixel);
                    }
                    //Draw Sub Sub memory
                    for(int j=1;j<splitSubSub;j++){
                    gc.drawLine(current+subPer*i+subSubPer*j,drawY,current+subPer*i+subSubPer*j,drawY+duration*subSubGridPixel);
                    }
                }
                //Draw Label
                String label=labelAt(index);
                drawLabelHorizontal(gc,current,drawY,label);
                current+=perMain;
                index++;
            }
        }else{
            int index=0;
            while(current>drawX-length){
                //Draw Main memory
                gc.drawLine(current,drawY,current,drawY+duration*mainGridPixel);
                int subPer=(int)(perMain/splitSub);
                int subSubPer=subPer/splitSubSub;
                //Draw Sub memory
                for(int i=0;i<splitSub;i++){
                    if(i!=0){
                    gc.drawLine(current-subPer*i,drawY,current-subPer*i,drawY+duration*subGridPixel);
                    }
                    //Draw Sub Sub memory
                    for(int j=1;j<splitSubSub;j++){
                    gc.drawLine(current-subPer*i-subSubPer*j,drawY,current-subPer*i-subSubPer*j,drawY+duration*subSubGridPixel);
                    }
                }
                //Draw Label
                String label=labelAt(index);
                drawLabelHorizontal(gc,current,drawY,label);
                current-=perMain;
                index++;
            }
        }
    }
    
    public Point stringExtent(Graphics gc,String label){
        int w=gc.getFontMetrics().getAverageCharWidth()*label.length();
        int h=gc.getFontMetrics().getHeight();
        return new Point(w,h);
    }
    private void drawLabelVertical(Graphics gc,int x,int y,String label){
        if(label.length()>0){
            Point extent=stringExtent(gc,label);
            int half_height=extent.y/2;
            
            if(gridPlus){
                gc.drawString(label,x+mainGridPixel+marginGrid,y-half_height);
            }else{
                gc.drawString(label,x-mainGridPixel-marginGrid-extent.x,y-half_height);
            }
        }
    }
    
    private void drawLabelHorizontal(Graphics gc,int x,int y,String label){
        if(label.length()>0){
            Point extent=stringExtent(gc,label);
            int half_width=extent.x/2;
            
            if(gridPlus){
                gc.drawString(label,x-half_width,y+mainGridPixel+marginGrid);
            }else{
                gc.drawString(label,x-half_width,y-mainGridPixel-marginGrid-extent.y);
            }
        }
    }
    
    /**
     * @param index
     * @return
     */
    
    private GraphLabelProvider labelProvider;
    private String labelAt(int index) {
        if(labelProvider!=null){
            return labelProvider.getLabel(this,index);
        }
        if(mainLabel!=null){
            if(index<mainLabel.length){
                return mainLabel[index];
            }
        }
        return "";
    }
    
    
    public GraphLabelProvider getLabelProvider() {
        return labelProvider;
    }
    public void setLabelProvider(GraphLabelProvider labelProvider) {
        this.labelProvider = labelProvider;
    }
}
